package com.group9.handinhand.dao;

import java.util.List;

import org.springframework.stereotype.Repository;

import com.group9.handinhand.dao.model.Community;
import com.group9.handinhand.dao.model.CommunityMember;
import com.group9.handinhand.dao.model.CommunityPost;
import com.group9.handinhand.dao.model.FriendshipRequest;
import com.group9.handinhand.dao.model.MembershipRequest;
import com.group9.handinhand.dao.model.User;
import com.group9.handinhand.service.so.UserTagSO;

@Repository
public class CommunityDao extends BaseDaoImpl {
	/**
	 * finds communities of user
	 * @param user
	 * @return
	 */
	public List<Community> findCommunitiesByUser(User user) {
		String queryString = "Select distinct (cm.community) from CommunityMember cm inner join cm.user us where us.id =:userId";
		return executeQueryString(queryString, "userId", user.getId());
	}
	/**
	 * finds communities by tag
	 * @param tag
	 * @return
	 */
	public List<Community> findCommunitiesByTag(UserTagSO tag) {
		String queryString = "Select distinct (ut.community) from CommunityTag ut inner join ut.tag tt where tt.id=:tagId";
		return executeQueryString(queryString, "tagId", tag.getTag().getId());
	}
	/**
	 * finds community by keyword
	 * @param keyword
	 * @return
	 */
	public List<Community> findCommunitiesByTagKeyword (String keyword) {
		String queryString = "Select distinct (ut.community) from CommunityTag ut inner join ut.tag tt where tt.tagName=:keyWord";
		return executeQueryString(queryString, "keyWord", keyword);
	}
	/**
	 * finds community by community name
	 * @param keyword
	 * @return
	 */
	public List<Community> findCommunitiesByName (String keyword) {
		String queryString = "from Community com where str(com.name) like :keyWord";
		return executeQueryString(queryString, "keyWord", "%"+keyword+"%");
	}
	
	public void updateCommunity(Community community) {
		update(community);		
	}

	public Community saveCommunity(Community community) {
		save(community);
		return community;
	}
	/**
	 * finds member of the community by his id
	 * @param communityId
	 * @param userId
	 * @return
	 */
	public CommunityMember findCommunityMemberByCommunityIdAndUserId(Long communityId, Long userId ) {
		String queryString = "from CommunityMember as cm  where cm.user.id =:userId and cm.community.id =:communityId";
		return executeQueryStringForObject(queryString, new String[]{"communityId" , "userId"}, new Object[]{communityId,userId});
		
	}
	/**
	 * finds community by community id or user id
	 * @param communityId
	 * @param userId
	 * @return
	 */
	public Community findModeratedCommunityByCommunityIdAndUserId(Long communityId, Long userId ) {
		String queryString = "Select c from Community c inner join c.moderators cm where cm.id =:userId and c.id =:communityId";
		return executeQueryStringForObject(queryString, new String[]{"communityId" , "userId"}, new Object[]{communityId,userId});
		
	}
	/**
	 * finds membership request by community id or user id
	 * @param communityId
	 * @param userId
	 * @return
	 */
	public MembershipRequest findMembershipRequestByCommunityIdAndUserId(Long communityId, Long userId ) {
		String queryString = "from MembershipRequest as mr where mr.user.id =:userId and mr.community.id =:communityId";
		return executeQueryStringForObject(queryString, new String[]{"communityId" , "userId"}, new Object[]{communityId,userId});
		
	}
	/**
	 * finds all membership requests off community
	 * @param communityId
	 * @return
	 */
	public List<MembershipRequest> findAllMembershipRequestsByCommunityId(Long communityId){
		String queryString = "from MembershipRequest as mr where mr.community.id =:communityId";
		return executeQueryString(queryString, new String[]{"communityId"},new Object[]{communityId});		
	}
	
	public CommunityMember saveCommunityMember(CommunityMember communityMember) {
		save(communityMember);
		return communityMember;
	}
	
	public MembershipRequest saveMembershipRequest(MembershipRequest membershipRequest) {
		save(membershipRequest);
		return membershipRequest;
	}
	/**
	 * finds community by community id
	 * @param communityId
	 * @return
	 */
	public Community findCommunityById(Long communityId) {
		Community community = (Community)findById(Community.class, communityId);
		return community;
	}

	public CommunityPost saveCommunityPost(CommunityPost communityPost) {
		save(communityPost);
		return communityPost;
	}
	/**
	 * find the moderator list by community id
	 * @param communityId
	 * @return
	 */
	public List<User> findModeratorsByCommunityId(Long communityId) {
		String queryString = "Select cm from Community c inner join c.moderators cm where c.id =:communityId";
		return executeQueryString(queryString, "communityId", communityId);
	}

	public void deleteMembershipRequest(MembershipRequest model) {
		delete(model);
	}

}
